import React from "react";
import { connect } from "react-redux";
import { Collapse } from "antd";
import _ from "lodash";
import { IState } from "store/reducers/cms";
import CMSComponent from "../CMSComponent";
import { CompEditSettingMap, typeMapping } from "./config";
import { SET_CMS_NODE_BASE_PROPS, SET_CMS_NODE_PROPS } from "store/constants";
import "./index.scss";
const { Panel } = Collapse;
interface ISettingTableProps {
    cms: IState,
    setCurrentProps: (payload: any) => void;
    setCurrentBaseProps: (payload: any) => void;
}
class SettingTable extends React.Component<ISettingTableProps> {
    get currentNode(){
        const { currentNode, config } = this.props.cms;
        if(Array.isArray(currentNode)){
            return currentNode.reduce((prev: any, cur: any, index: number) => {
                if(!prev) return {};
                const node = prev.find((item: any) => item.id === cur);
                if(!node) return null;
                return index === currentNode.length - 1 ? node : node.children || node;
            }, config)
        }
        return config.find(item => item.id === currentNode)
    }
    handleEditColumns = (columns: any) => {
        let columnsList: {[key: string]: any} = {};
        Object.keys(columns).forEach(key => {
            if(Reflect.has(columnsList, columns[key]?.type)){
                columnsList[columns[key]?.type].push({
                    key,
                    ...columns[key]
                })
            }else{
                columnsList[columns[key]?.type] = [{
                    key,
                    ...columns[key]
                }]
            }
        });
        return Object.keys(columnsList).map(key => {
            return {
                key,
                title: typeMapping[key],
                list: columnsList[key]
            }
        })
    }
    // 设置当前节点的属性信息
    setCurrentProps = (key: string, value: any, type: string, field?: any) => {
        if(field){
            const currentNode = this.currentNode;
            if(key === "customeFormExtra"){
                this.props.setCurrentProps({
                    [field]: value
                })
                return
            }
            if(key === "required" || key === "requiredMessage"){
                const { rules = [] } = currentNode?.props?.[field] || {};
                const { required, message } = rules.find((item: any) => Reflect.has(item, "required")) || {};
                value = [{required: key === "required" ? value : !!required, message: key === "requiredMessage" ? value : (message || "内容不能为空")}];
                key = "rules";
            }
            if(field.split(".")?.length === 2){
                const [newField, childField] = field.split(".");
                field = newField;
                value = { 
                    ...currentNode?.props?.[field]?.[childField],
                    [key]: value
                };
                key = childField;
            }
            this.props.setCurrentProps({
                [field]: {
                    ...currentNode?.props?.[field],
                    [key]: value
                }
            })
            return;
        }
        if(type === "style"){
            const currentNode = this.currentNode;
            value = {
                ...currentNode?.props?.style,
                [key]: value
            };
            key = "style";
        }
        if(["children"].includes(key)){
            this.props.setCurrentBaseProps({
                [key]: value
            })
            return
        }
        this.props.setCurrentProps({
            [key]: value
        })
    }
    render(){
        const currentNode = this.currentNode;
        if(!currentNode) return null;
        const editColumns = CompEditSettingMap[currentNode.component];
        if(!editColumns) return null;
        return <div className="cms-setting-wrapper">
            <Collapse defaultActiveKey={["basic"]}>
                {
                    this.handleEditColumns(editColumns).map(item => {
                        return <Panel header={item.title} key={item.key}>
                            {
                                item.list.map((col: any) => {
                                    const props = currentNode?.props || {};
                                    const needSendProps = _.pick(props, ["options"]);
                                    const replyProps = col?.reply ? col?.reply(props) : {}
                                    const value = col.getValue ? col.getValue(props, currentNode) : {
                                        value: _.get(props, col.key)
                                    }
                                    return <div className="edit-item" key={col.key}>
                                        {
                                            col?.label && (<label className="edit-label">{col?.label}</label>)
                                        }
                                        <div className="edit-control">
                                            <CMSComponent is={col.tag} {...col.props} {...needSendProps} onChange={(e: any) => {
                                               let value = e;
                                               if(col.afterTransform) value = col.afterTransform(e, currentNode);
                                               this.setCurrentProps(col.key, value, item.key, col?.field)
                                            }} {...replyProps} {...value} />
                                        </div>
                                    </div>
                                })
                            }
                        </Panel>
                    })
                }
            </Collapse>
        </div>
    }
}

export default connect((state: any) => {
    return {
        cms: state.cms
    }
}, (dispatch: any) => {
    return {
        setCurrentProps: (payload: any) => dispatch({type: SET_CMS_NODE_PROPS, payload}),
        setCurrentBaseProps: (payload: any) => dispatch({type: SET_CMS_NODE_BASE_PROPS, payload})
    }
})(SettingTable);